﻿using Microsoft.Extensions.Logging;
using RotovapPlatform.Domain.Business.Recipes.Entities;
using RotovapPlatform.Domain.Services.Scheduling;
using System;
using System.Threading.Tasks;

namespace RotovapPlatform.Application.Services.Experiments
{
	/// <summary>
	/// 实验流程协调服务，负责连接任务调度服务和实验流程服务
	/// 不依赖于BackgroundService，而是通过事件订阅方式实现
	/// </summary>
	public class ExperimentProcessCoordinator : IExperimentProcessCoordinator, IDisposable
	{
		private readonly ILogger<ExperimentProcessCoordinator> _logger;
		private readonly ITaskSchedulingDomainService _taskSchedulingDomainService;
		private readonly IExperimentProcessAppService _experimentProcessAppService;
		private bool _isInitialized = false;
		private bool _disposed = false;

		// 最后一个被变更的实验ID，用于避免重复处理同一个实验
		private Guid? _lastChangedExperimentId;

		/// <summary>
		/// 构造函数
		/// </summary>
		public ExperimentProcessCoordinator(
			ILogger<ExperimentProcessCoordinator> logger,
			ITaskSchedulingDomainService taskSchedulingDomainService,
			IExperimentProcessAppService experimentProcessAppService)
		{
			_logger = logger;
			_taskSchedulingDomainService = taskSchedulingDomainService;
			_experimentProcessAppService = experimentProcessAppService;
		}

		/// <summary>
		/// 初始化服务，注册事件处理
		/// </summary>
		public void Initialize()
		{
			if (_isInitialized)
			{
				return;
			}

			_logger.LogInformation("实验流程协调服务初始化");

			// 注册事件处理程序
			_taskSchedulingDomainService.CurrentExperimentChanged += HandleCurrentExperimentChanged;

			_isInitialized = true;
			_logger.LogInformation("实验流程协调服务已启动");
		}

		/// <summary>
		/// 处理当前实验变更事件
		/// </summary>
		private async void HandleCurrentExperimentChanged(object sender, CurrentExperimentChangedEventArgs e)
		{
			try
			{
				var experiment = e.CurrentExperiment;
				if (experiment == null)
				{
					_logger.LogInformation("当前实验已清除");
					return;
				}

				// 避免重复处理同一个实验
				if (_lastChangedExperimentId == experiment.ExperimentId)
				{
					_logger.LogDebug($"实验 {experiment.ExperimentId} 已在处理中，跳过");
					return;
				}

				_logger.LogInformation($"接收到当前实验变更事件: {experiment.ExperimentId}，准备执行实验");

				// 更新最后处理的实验ID
				_lastChangedExperimentId = experiment.ExperimentId;

				// 启动执行实验的任务
				_ = Task.Run(async () =>
				{
					try
					{
						// 调用实验流程应用服务执行实验
						_logger.LogInformation($"开始执行实验: {experiment.ExperimentId} - {experiment.ExperimentName}");
						var result = await _experimentProcessAppService.ExecuteExperimentAsync(experiment.ExperimentId);

						if (result != null)
						{
							_logger.LogInformation($"实验 {experiment.ExperimentId} 执行完成，状态: {result.Status}");
						}
						else
						{
							_logger.LogWarning($"实验 {experiment.ExperimentId} 执行结果为null");
						}
					}
					catch (Exception ex)
					{
						_logger.LogError(ex, $"执行实验 {experiment.ExperimentId} 时发生错误");
					}
				});
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "处理当前实验变更事件时发生错误");
			}
		}

		/// <summary>
		/// 释放资源
		/// </summary>
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		/// <summary>
		/// 释放资源
		/// </summary>
		/// <param name="disposing">是否释放托管资源</param>
		protected virtual void Dispose(bool disposing)
		{
			if (!_disposed)
			{
				if (disposing)
				{
					// 取消事件注册
					if (_isInitialized)
					{
						_taskSchedulingDomainService.CurrentExperimentChanged -= HandleCurrentExperimentChanged;
						_logger.LogInformation("实验流程协调服务已停止");
					}
				}

				_disposed = true;
			}
		}

		/// <summary>
		/// 析构函数
		/// </summary>
		~ExperimentProcessCoordinator()
		{
			Dispose(false);
		}
	}
}